package cn.cf.kxx.service;

import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.util.Log;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.app.NotificationCompat;

import com.serotonin.modbus4j.ModbusFactory;
import com.serotonin.modbus4j.ModbusMaster;
import com.serotonin.modbus4j.exception.ModbusInitException;
import com.serotonin.modbus4j.exception.ModbusTransportException;
import com.serotonin.modbus4j.msg.ModbusRequest;
import com.serotonin.modbus4j.msg.ModbusResponse;
import com.serotonin.modbus4j.msg.ReadCoilsRequest;
import com.serotonin.modbus4j.msg.ReadCoilsResponse;
import com.serotonin.modbus4j.msg.ReadDiscreteInputsRequest;
import com.serotonin.modbus4j.msg.ReadDiscreteInputsResponse;
import com.serotonin.modbus4j.msg.ReadHoldingRegistersRequest;
import com.serotonin.modbus4j.msg.ReadHoldingRegistersResponse;
import com.serotonin.modbus4j.msg.ReadInputRegistersRequest;
import com.serotonin.modbus4j.msg.ReadInputRegistersResponse;
import com.serotonin.modbus4j.msg.WriteCoilRequest;
import com.serotonin.modbus4j.msg.WriteCoilResponse;
import com.serotonin.modbus4j.msg.WriteMaskRegisterRequest;
import com.serotonin.modbus4j.msg.WriteRegisterRequest;
import com.serotonin.modbus4j.msg.WriteRegisterResponse;
import com.serotonin.modbus4j.msg.WriteRegistersRequest;

import org.apache.commons.lang3.StringUtils;

import java.util.Arrays;
import java.util.concurrent.ConcurrentLinkedDeque;
import java.util.concurrent.ConcurrentLinkedQueue;

import cn.cf.kxx.R;
import cn.cf.kxx.tools.AndroidWrapper;
import cn.cf.kxx.tools.Tools;

public class SerialService extends Service {

    public static final String action = "cn.cf.kxx.service";
    private static final int NOTIFICATION_ID = 1;

    // 创建通知渠道（如果需要）
    String channelId = "channel_id";
    CharSequence channelName = "Channel Name";
    //站号
    private int id = 0;
    private boolean isRunning = false;
    private Thread ttyS1Thread,ttyS7Thread,ttyS3Thread;
    //轮询顺序
    ConcurrentLinkedDeque<ModbusRequest> queue = new ConcurrentLinkedDeque<>();

    @Override
    public void onCreate() {
        super.onCreate();
        Log.e("dong","onCreate");
        // 创建并显示前台通知
        createNotification();
    }

    private RemoteCallbackList<IMyAidlCallBack> callbacks = new RemoteCallbackList<>();

    ISerialAidlInterface.Stub iSerialAidlInterface = new ISerialAidlInterface.Stub() {

        @Override
        public void registerCallback(IMyAidlCallBack callback, int sid) throws RemoteException {
            if(callback != null){
                callbacks.register(callback);
            }
            id = sid;
            queue.clear();
        }

        @Override
        public void unregisterCallback(IMyAidlCallBack callback) throws RemoteException {
            if (callback != null) {
                callbacks.unregister(callback);
            }
        }

        @Override
        public void sendMessage(int fun,int startAdr,int len,byte[] data) throws RemoteException {
            //执行发送
            try {
                switch (fun){
                    case 0x03:
                        queue.addFirst(new ReadHoldingRegistersRequest(id,startAdr,len));
                        break;
                    case 0x04:
                        queue.addFirst(new ReadInputRegistersRequest(id,startAdr,len));
                        break;
                    case 0x05:
                        queue.addFirst(new WriteCoilRequest(id,startAdr,data[0] == 1));
                        break;
                    case 0x10:
                        short[] inputValue = new short[len];
                        for(int i = 0;i<len;i++){
                            inputValue[i] = (short) ((data[i*2] << 8) | data[i*2+1]);

                        }
                        queue.addFirst(new WriteRegistersRequest(id,startAdr, inputValue));
                        break;
                }
            } catch (ModbusTransportException e) {
            }

        }
    };

    // 在需要的时候调用回调方法

    private void performCallback(byte fun,byte[] bytes,boolean error) {

        final int count = callbacks.beginBroadcast();
        for (int i = 0; i < count; i++) {
            try {
                if(error){
                    callbacks.getBroadcastItem(i).onCallError(fun);
                }else{
                    callbacks.getBroadcastItem(i).onCallback(fun,bytes);
                }

            } catch (RemoteException e) {
                Log.e("MyService", "Error in callback", e);
            }
        }
        callbacks.finishBroadcast();
    }

    @Override
    public IBinder onBind(@NonNull Intent intent) {
        Log.e("dong","onBind");
        return iSerialAidlInterface;
    }

    @Override
    public boolean onUnbind(Intent intent) {
        Log.e("dong","onUnbind");
        return super.onUnbind(intent);
    }

    private void createNotification() {
        // 创建 NotificationManager 对象
        NotificationManager notificationManager = getSystemService(NotificationManager.class);

        int importance = NotificationManager.IMPORTANCE_DEFAULT;

        NotificationChannel channel = new NotificationChannel(channelId, channelName, importance);
        // 设置其他通知渠道属性（如描述、声音、震动等）
        // ...

        // 注册通知渠道
        notificationManager.createNotificationChannel(channel);

        // 创建通知构建器
        NotificationCompat.Builder builder = new NotificationCompat.Builder(this, channelId)
                .setSmallIcon(R.mipmap.ic_launcher)
                .setContentTitle("系统任务")
                .setContentText("串口服务运行中...")
                .setPriority(NotificationCompat.PRIORITY_DEFAULT)
                .setVisibility(NotificationCompat.VISIBILITY_PRIVATE);

        // 设置其他通知属性（如大图、进度条、点击行为等）
        // ...

        // 创建通知对象
        Notification notification = builder.build();
        startForeground(NOTIFICATION_ID, notification);
    }

    @Override
    public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
        Log.e("dong","onStartCommand");
        if (!isRunning) {
            isRunning = true;
            startLoop();
        }
        return START_REDELIVER_INTENT;
    }

    private void startLoop() {
        ttyS1Thread = new Thread(() -> {
            ModbusMaster master = null;
            ModbusRequest request = null;
            ModbusResponse response = null;

            ReadHoldingRegistersResponse holdResponse;
            ReadCoilsResponse coilsResponse;
            ReadInputRegistersResponse inputResponse;
            WriteCoilResponse writeCoilResponse;
            WriteRegisterResponse writeRegisterResponse;

                while (isRunning) {
                    try {
                        if(id < 1){
                            Thread.sleep(1000);
                            continue;
                        }

                        if(queue.size() < 2){
                            queue.add(new ReadCoilsRequest(id,0,7));
                            queue.add(new ReadInputRegistersRequest(id,0,10));
                        }

                        if(master == null){
//                            master = getMaster("/dev/ttyS1");
                            master = getMaster("/dev/ttyS3");
                        }

                        while ((request = queue.poll()) != null){
                            response = master.send(request);
                            response.validateResponse(request);

                            if(response instanceof ReadCoilsResponse){
                                coilsResponse = (ReadCoilsResponse) response;
                                performCallback(coilsResponse.getFunctionCode(),coilsResponse.getData(),coilsResponse.isException());
                            }else if(response instanceof ReadInputRegistersResponse){
                                inputResponse = (ReadInputRegistersResponse) response;
                                performCallback(inputResponse.getFunctionCode(),inputResponse.getData(),inputResponse.isException());
                            }else if(response instanceof ReadHoldingRegistersResponse){
                                holdResponse = (ReadHoldingRegistersResponse) response;
                                performCallback(holdResponse.getFunctionCode(),holdResponse.getData(),holdResponse.isException());
                            }else if(response instanceof WriteCoilResponse){
                                writeCoilResponse = (WriteCoilResponse) response;
                                performCallback(writeCoilResponse.getFunctionCode(),null,writeCoilResponse.isException());
                            }else if(response instanceof WriteRegisterResponse){
                                writeRegisterResponse = (WriteRegisterResponse) response;
                                performCallback(writeRegisterResponse.getFunctionCode(),null,writeRegisterResponse.isException());
                            }
                        }
                    } catch (ModbusInitException e){
                        Log.e("dong","初始化错误");
                        master = null;
                    } catch (ModbusTransportException e) {
                        Log.e("dong","超时了而已");
                        performCallback(response!= null ? response.getFunctionCode() : (byte)0,null,true);
//                        master.destroy();
                        master = null;
                    } catch (InterruptedException e) {
                        Log.e("dong","其他错误");
                        master = null;
                    }
                }
                if(master != null && master.isConnected()){
                    master.destroy();
                }

        });
        ttyS1Thread.start();

//        ttyS7Thread = new Thread(() -> {
//            while (isRunning) {
//                // 执行循环操作，处理数据
//                try {
//                    Thread.sleep(1000);
//                    Log.e("dong","ttyS7Thread");
//                } catch (InterruptedException e) {
//                    throw new RuntimeException(e);
//                }
//            }
//        });
//        ttyS7Thread.start();
//        ttyS3Thread = new Thread(() -> {
//            while (isRunning) {
//                // 执行循环操作，处理数据
//                try {
//                    Thread.sleep(1000);
//                    Log.e("dong","ttyS3Thread");
//                } catch (InterruptedException e) {
//                    throw new RuntimeException(e);
//                }
//            }
//        });
//        ttyS3Thread.start();
    }

    private void stopLoop() {
        isRunning = false;
        if (ttyS1Thread != null) {
            try {
                ttyS1Thread.join(); // 等待线程结束
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
//        if (ttyS7Thread != null) {
//            try {
//                ttyS7Thread.join(); // 等待线程结束
//            } catch (InterruptedException e) {
//                e.printStackTrace();
//            }
//        }
//        if (ttyS3Thread != null) {
//            try {
//                ttyS3Thread.join(); // 等待线程结束
//            } catch (InterruptedException e) {
//                e.printStackTrace();
//            }
//        }
    }

    /**
     * 工厂。
     */
    ModbusFactory modbusFactory;
    /**
     * 获取master
     *
     * @return
     * @throws ModbusInitException
     */
    public ModbusMaster getMaster(String s) throws ModbusInitException {
        if (modbusFactory == null) {
            modbusFactory = new ModbusFactory();
        }
        ModbusMaster master = modbusFactory.createRtuMaster(new AndroidWrapper(s));
        master.init();
        //重试次数，避免总是触发超时
        master.setRetries(10);
        return master;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        stopLoop();
    }
}
